﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufBase.h"
#include "GnufItem.h"
#include "GnufSearchBox.h"
#include "GnufDropDownBoard.h"

namespace gnuf {
    class Info;
    class QtLineEditComboBox;
    class SearchDataModel;
    class LineEditComboBoxAppearanceSetting;
    class LineEditComboBox;
    class Text;

    class LineEditComboBoxSearchDataModel final : public SearchDataModel
    {
    public:
        LineEditComboBoxSearchDataModel(LineEditComboBox* lineEditComboBox):m_lineEditComboBox(lineEditComboBox) {}
        virtual ~LineEditComboBoxSearchDataModel() {}

    public:
        virtual const std::list<std::wstring> search(const std::wstring&) override;
    private:
        LineEditComboBox* m_lineEditComboBox;
    };

    class GNUF_BASE_EXPORT LineEditComboBox final 
        : public ItemWith<QtLineEditComboBox>
        , public IDropDownBoardObserver
    {
    public:
        static const EItemType Type;
        explicit LineEditComboBox(Item*);
        virtual ~LineEditComboBox();
    public:
        void assignInfo(const Info&);
        void addMenuItem(const Info&,bool hasBadge = false);
        void setMenuItemBadge(int index, bool on = true);
        void removeMenuItem(int index);
        void removeMenuItem(Item*);
        void removeAllMenuItem();

        const std::wstring getCurrentText() const;

        void customizeLineEditComboBoxAppearanceSetting(gcmp::OwnerPtr<LineEditComboBoxAppearanceSetting>&&);
        const LineEditComboBoxAppearanceSetting* customizeAppearanceSetting() const { return m_customizeAppearanceSetting.get(); }

        std::wstring arrowIconPath();
        void setArrowIcon(const std::wstring&);

        //控制搜索功能是否生效
        void setSearchEnabled(bool isEnable) { m_bSearchEnabled = isEnable; }
        bool getSearchEnabled() { return m_bSearchEnabled; }

        DropDownBoard* dropDownBoard() { return m_dropDownBoard.get(); }

        typedef std::function<void(std::list<std::wstring>&)> Filter;
        void search(const std::wstring& text,const Filter& filter = nullptr);

        void setErrorInfo(const std::wstring& errorInfo);

        void setCurrentIndex(int index);
        void setCurrentText(const std::wstring& text);
        void setLineEditContent(const std::wstring&);

        void setDisplayNumberPerPage(int num);
        int displayNumberPerPage();

        void selectItem(const std::wstring&);

    protected:
        // Inherits from Item...
        virtual void onDisconnectFromMyQtItem() override;
        virtual void onPostAppearanceSettingChanged() override;
        virtual void onPostInfoChanged() override;
        virtual void onPostAbilityChanged() override;
        // Inherits from IDropDownBoardObserver
        virtual void onBoardItemClicked(Item* item) override;

    private:
        //将item设置为选中状态
        void selectItem(Item* item);
        //根据content查找item
        Item* findItemByContent(const std::wstring&);
        //将搜索结果设置可见
        void displaySearchResult(const std::list<std::wstring>&);
        //将所有item设置为可见
        void displayAllItem();
        void onSearchFinished(const std::list<std::wstring>&);
        void setDisplayText(const std::wstring&, bool wantToNotify = false);
    private:
        gcmp::OwnerPtr<Info> m_info;
        gcmp::OwnerPtr<Info> m_iconInfo;
        gcmp::OwnerPtr<Text> m_errorText;
        gcmp::OwnerPtr<DropDownBoard> m_dropDownBoard;
        gcmp::OwnerPtr<SearchDataModel> m_modelData;
        gcmp::OwnerPtr<LineEditComboBoxAppearanceSetting> m_customizeAppearanceSetting;
        bool m_bSearchEnabled;
        std::wstring m_currentContent;
        friend class QtLineEditComboBox;
    };
}
